package com.binguo.service;

import com.binguo.common.enums.CategoryType;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.sms.Result;
import com.binguo.model.api.vo.MajorCategoryVO;
import com.binguo.model.api.vo.MinorCategoryVO;
import com.binguo.model.api.vo.ProductVO;
import com.binguo.model.mapper.*;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.yprecapi.YpRecService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import static com.binguo.common.constants.ProductConstants.*;
import static com.binguo.common.exception.ErrorCode.PRODUCT_NOT_EXISTS;


/**
 * Created by haibang on 18/5/7.
 */
@Service
public class ProductService {

    @Autowired
    ProductCategoryRepository productCategoryRepository;

    @Autowired
    ProductRepository productRepository;

    @Autowired
    LogProductImgRepository logProductImgRepository;

    @Resource
    LogProductImgFromUserMapper logProductImgFromUserMapper;
    @Autowired
    LogProductImgFromUserRepository logProductImgFromUserRepository;
    @Resource
    ProductInventoryMapper productInventoryMapper;
    @Resource
    LogProductImgMapper logProductImgMapper;
    @Resource
    ProductMapper productMapper;
    @Resource
    ProductYpMapper productYpMapper;
    @Resource
    ProductYpRefMapper productYpRefMapper;
    @Resource
    ShopProductYpTypeRefMapper shopProductYpTypeRefMapper;
    @Resource
    ShopProductVersionMapper shopProductVersionMapper;
    @Resource
    ProductPriceMapper productPriceMapper;
    @Resource
    ShopHoursConfigMapper shopHoursConfigMapper;
    @Resource
    ShopProductRefMapper shopProductRefMapper;

    @Resource
    BranchMapper branchMapper;
    @Resource
    ProductSubMapper productSubMapper;

    @Resource
    ShopBaiduUrlCurMapper shopBaiduUrlCurMapper;

    @Autowired
    ShopRepository shopRepository;

    @Autowired
    YpRecService ypRecService;


    SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");


    public List<LogProductImgFromUser> getImgListByProductId(Integer productId) {
        Condition logProductImgFromUserConditon = new Condition(LogProductImgFromUser.class);
        logProductImgFromUserConditon.or().andEqualTo("productId", productId);

        List<LogProductImgFromUser> logProductImgFromUserList =
                logProductImgFromUserMapper.selectByCondition(logProductImgFromUserConditon);

        return logProductImgFromUserList;
    }

    public List<LogProductImgFromUser> eraseShopBaiduUrlCur(Integer shopId) {
        Condition condition = new Condition(ShopBaiduUrlCur.class);
        condition.or().andEqualTo("shopId", shopId);
        List<ShopBaiduUrlCur> shopBaiduUrlCurList = shopBaiduUrlCurMapper.selectByCondition(condition);


        if (shopBaiduUrlCurList != null && shopBaiduUrlCurList.size() > 0) {
            for (ShopBaiduUrlCur shopBaiduUrlCur : shopBaiduUrlCurList) {

                Condition logProductImgFromUserConditon = new Condition(LogProductImgFromUser.class);
                logProductImgFromUserConditon.or().andEqualTo("shopId", shopId)
                        .andEqualTo("subDb", 1)
                        .andEqualTo("baiduDeleted", 0)
                ;

                List<LogProductImgFromUser> logProductImgFromUserList =
                        logProductImgFromUserMapper.selectByCondition(logProductImgFromUserConditon);

                return logProductImgFromUserList;
            }
        }

        return null;
    }

    public void addShopProductVersion(Integer shopId) {
        Condition condition = new Condition(ShopProductVersion.class);
        condition.or().andEqualTo("shopId", shopId);
        List<ShopProductVersion> shopProductVersionList = shopProductVersionMapper.selectByCondition(condition);

        if (shopProductVersionList != null && shopProductVersionList.size() > 0) {
            for (ShopProductVersion shopProductVersion : shopProductVersionList) {
                ShopProductVersion temp = new ShopProductVersion();
                temp.setId(shopProductVersion.getId());
                temp.setProductVersion(shopProductVersion.getProductVersion() + 1);

                shopProductVersionMapper.updateByPrimaryKeySelective(temp);
            }
        }
    }

    public ShopProductVersion getShopProductVersion(Integer shopId, String deviceId) {
        Condition condition = new Condition(ShopProductVersion.class);
        condition.or().andEqualTo("shopId", shopId);
        List<ShopProductVersion> shopProductVersionList = shopProductVersionMapper.selectByCondition(condition);

        if (shopProductVersionList != null && shopProductVersionList.size() > 0) {
            return shopProductVersionList.get(0);
        }else {
            return null;
        }
    }

    public List<ProductYp> getYpProductList(Integer shopId){
        if (shopId != null) {
            Condition condition = new Condition(ShopProductYpTypeRef.class);
            condition.or().andEqualTo("shopId", shopId);

            List<ShopProductYpTypeRef> shopProductYpTypeRefList = shopProductYpTypeRefMapper.selectByCondition(condition);
            if (shopProductYpTypeRefList != null && shopProductYpTypeRefList.size() > 0) {
                List<Integer> productTypeIdList =
                        shopProductYpTypeRefList.stream().map(ShopProductYpTypeRef::getProductTypeId)
                                .collect(Collectors.toList());

                Condition productYpCondition = new Condition(ProductYp.class);
                productYpCondition.or().andIn("productType", productTypeIdList);

                return productYpMapper.selectByCondition(productYpCondition);
            }
        }
        return productYpMapper.selectAll();
    }
    public List<Integer> getYpProduct(Integer productId, Integer shopId, Integer branchId){
        Condition condition = new Condition(ProductYpRef.class);
        condition.or().andEqualTo("shopId", shopId)
                .andEqualTo("branchId", branchId)
                .andEqualTo("productId", productId)
        ;

        List<ProductYpRef> productYpRefList = productYpRefMapper.selectByCondition(condition);
        if (productYpRefList != null && productYpRefList.size() > 0) {
            return productYpRefList.stream().map(ProductYpRef::getYpProductId).collect(Collectors.toList());
        }
        return null;
    }

    public void refYpProduct(Integer shopId, Integer productId,
                             Integer ypProductId, String productName){
        Product product = productMapper.selectByPrimaryKey(productId);
        ProductYp productYp = productYpMapper.selectByPrimaryKey(ypProductId);
        ProductYpRef productYpRef = new ProductYpRef();
        productYpRef.setProductId(productId);
        productYpRef.setShopId(shopId);
        productYpRef.setYpProductId(ypProductId);
        productYpRef.setProductName(productName);
        productYpRef.setBaiduTagName(productYp.getBaiduTagName());
        productYpRef.setBranchId(product.getStoreid());
        productYpRef.setSearchCode(productYp.getSearchCode());
        productYpRefMapper.insertSelective(productYpRef);

        Condition condition = new Condition(ShopProductRef.class);
        condition.or().andEqualTo("shopId", product.getShopid());
        condition.or().andEqualTo("refShopId", product.getShopid());

        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(condition);

        if (shopProductRefList != null && shopProductRefList.size() > 0) {

            for (ShopProductRef shopProductRef : shopProductRefList) {
                ProductYpRef tempProduct = new ProductYpRef();
                BeanUtils.copyProperties(productYpRef, tempProduct);

                if (shopProductRef.getShopId().equals(product.getShopid())) {

                    tempProduct.setShopId(shopProductRef.getRefShopId());
                }else {
                    tempProduct.setShopId(shopProductRef.getShopId());
                }
                tempProduct.setId(null);

                Condition branchCondition = new Condition(Branch.class);
                branchCondition.or().andEqualTo("shopId", tempProduct.getShopId());
                List<Branch> branchList = branchMapper.selectByCondition(branchCondition);
                if (branchList != null && branchList.size() > 0) {
                    tempProduct.setBranchId(branchList.get(0).getBranchId());
                }else {
                    tempProduct.setBranchId(null);
                }

                productYpRefMapper.insertSelective(tempProduct);
            }
        }
    }



    public void delRefYpProduct(Integer shopId, Integer productId){
        Condition condition = new Condition(ProductYpRef.class);
        condition.or().andEqualTo("shopId", shopId)
                .andEqualTo("productId", productId)
        ;

        productYpRefMapper.deleteByCondition(condition);


        Condition shopCondition = new Condition(ShopProductRef.class);
        shopCondition.or().andEqualTo("shopId", shopId);
        shopCondition.or().andEqualTo("refShopId", shopId);

        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(shopCondition);

        if (shopProductRefList != null && shopProductRefList.size() > 0) {

            Product product = productMapper.selectByPrimaryKey(productId);
            for (ShopProductRef shopProductRef : shopProductRefList) {
                Integer targetShopId = null;

                if (shopProductRef.getShopId().equals(shopId)) {

                    targetShopId = shopProductRef.getRefShopId();
                }else {
                    targetShopId = shopProductRef.getShopId();
                }


                Condition productConditon = new Condition(Product.class);
                productConditon.or().andEqualTo("shopid", targetShopId)
                        .andEqualTo("searchcode", product.getSearchcode())
                ;
                List<Product> productList = productMapper.selectByCondition(productConditon);

                Integer targetProductId = null;
                if (productList != null && productList.size() > 0) {

                    Product targetProduct = productList.get(0);
                    targetProductId = targetProduct.getId();
                }

                if (targetProductId == null) {
                    continue;
                }


                Condition productYpRefCondition = new Condition(ProductYpRef.class);
                productYpRefCondition.or().andEqualTo("shopId", targetShopId)
                        .andEqualTo("productId", targetProductId)
                ;

                productYpRefMapper.deleteByCondition(condition);
            }
        }
    }


    public Integer addProduct(Product product){
        productRepository.save(product);


        Condition condition = new Condition(ShopProductRef.class);
        condition.or().andEqualTo("shopId", product.getShopid());
        condition.or().andEqualTo("refShopId", product.getShopid());

        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(condition);

        if (shopProductRefList != null && shopProductRefList.size() > 0) {

            for (ShopProductRef shopProductRef : shopProductRefList) {
                Product tempProduct = new Product();
                BeanUtils.copyProperties(product, tempProduct);

                if (shopProductRef.getShopId().equals(product.getShopid())) {

                    tempProduct.setShopid(shopProductRef.getRefShopId());
                }else {
                    tempProduct.setShopid(shopProductRef.getShopId());
                }
                tempProduct.setId(null);

                productRepository.save(tempProduct);
            }
        }

        return product.getId();
    }

    public void addProductInventory(ProductInventory productInventory){
        productInventoryMapper.insertSelective(productInventory);
    }

    public void updateProductInventory(ProductInventory productInventory){
        productInventoryMapper.updateByPrimaryKeySelective(productInventory);
    }

    public int countProductByShop(Integer shopId) {
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("shopid", shopId);
        List<Product> list = productRepository.findByCondition(condition);
        return list.size();
    }


    public int countProductNameByShopAndBranchPos(String productName, Integer shopId, Integer branchId) {
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("name", productName)
            .andEqualTo("storeid", branchId)
            .andEqualTo("shopid", shopId)
            .andEqualTo("productType", 1)
            .andEqualTo("deleted", false)
        ;
        List<Product> list = productRepository.findByCondition(condition);
        return list.size();
    }

    public int countProductNameByShopAndBranch(String productName, Integer shopId, Integer branchId) {
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("name", productName)
            .andEqualTo("storeid", branchId)
            .andEqualTo("shopid", shopId)
            .andEqualTo("productType", 2)
            .andEqualTo("deleted", false)
        ;
        List<Product> list = productRepository.findByCondition(condition);
        return list.size();
    }

    public int countProductNameByShopAndBranchBeforeUpdatePos(String productName, Integer shopId, Integer branchId, Integer curProductId) {
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("name", productName)
            .andEqualTo("storeid", branchId)
            .andEqualTo("shopid", shopId)
            .andEqualTo("productType", 1)
            .andEqualTo("deleted", false)
            .andNotEqualTo("id", curProductId)
        ;
        List<Product> list = productRepository.findByCondition(condition);
        return list.size();
    }

    public int countProductNameByShopAndBranchBeforeUpdate(String productName, Integer shopId, Integer branchId, Integer curProductId) {
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("name", productName)
            .andEqualTo("storeid", branchId)
            .andEqualTo("shopid", shopId)
            .andEqualTo("productType", 2)
            .andEqualTo("deleted", false)
            .andNotEqualTo("id", curProductId)
        ;
        List<Product> list = productRepository.findByCondition(condition);
        return list.size();
    }

    public void updateProduct(Product product){
        productRepository.update(product);
    }

    public Product getShopProductRefProductId(Integer productId, Integer shopId) {

        Condition condition = new Condition(ShopProductRef.class);
        condition.or().andEqualTo("shopId", shopId);
        condition.or().andEqualTo("refShopId", shopId);

        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(condition);

        if (shopProductRefList != null && shopProductRefList.size() > 0) {
            Product sourceProduct = getProductById(productId);

            for (ShopProductRef shopProductRef : shopProductRefList) {
                Integer targetShopId = null;

                if (shopProductRef.getShopId().equals(shopId)) {

                    targetShopId = shopProductRef.getRefShopId();
                } else {
                    targetShopId = shopProductRef.getShopId();
                }

                Condition productConditon = new Condition(Product.class);
                productConditon.or().andEqualTo("shopid", targetShopId)
                        .andEqualTo("searchcode", sourceProduct.getSearchcode())
                ;
                List<Product> productList = productMapper.selectByCondition(productConditon);
                if (productList != null && productList.size() > 0) {

                    Product targetProduct = productList.get(0);
                    return targetProduct;
                }
            }
        }
        return null;
    }

    public void updateProductSelective(Product product){
        productMapper.updateByPrimaryKeySelective(product);


        Condition condition = new Condition(ShopProductRef.class);
        condition.or().andEqualTo("shopId", product.getShopid());
        condition.or().andEqualTo("refShopId", product.getShopid());

        List<ShopProductRef> shopProductRefList = shopProductRefMapper.selectByCondition(condition);

        if (shopProductRefList != null && shopProductRefList.size() > 0) {
            Product sourceProduct = getProductById(product.getId());

            for (ShopProductRef shopProductRef : shopProductRefList) {
                Integer targetShopId = null;

                if (shopProductRef.getShopId().equals(product.getShopid())) {

                    targetShopId = shopProductRef.getRefShopId();
                }else {
                    targetShopId = shopProductRef.getShopId();
                }

                Condition productConditon = new Condition(Product.class);
                productConditon.or().andEqualTo("shopid", targetShopId)
                        .andEqualTo("searchcode", sourceProduct.getSearchcode())
                ;
                List<Product> productList = productMapper.selectByCondition(productConditon);
                if (productList != null && productList.size() > 0) {

                    Product targetProduct = productList.get(0);

                    Product temp = new Product();
                    temp.setId(targetProduct.getId());
                    temp.setName(product.getName());
                    temp.setMinorcategoryid(product.getMinorcategoryid());
                    temp.setPrice(product.getPrice());

                    productMapper.updateByPrimaryKeySelective(temp);
                }
            }
        }
    }

    public void changeProductStatus(Integer productId, Integer status){
        Product product = new Product();
        product.setId(productId);
        product.setStatus(status.byteValue());

        productRepository.update(product);
    }

    public List<LogProductImg> getAllProductImgList(Integer productId){
        Condition condition = new Condition(LogProductImg.class);
        condition.or().andEqualTo("productId", productId)
                .andEqualTo("baiduDeleted", 0)
                .andIsNotNull("contSign")
        ;
        List<LogProductImg> logProductImgList = logProductImgRepository.findByCondition(condition);

        if (logProductImgList != null && logProductImgList.size() > 0) {
            return logProductImgList;
        }
        return null;
    }

    public List<LogProductImg> getProductImgList(Integer productId){
        Condition condition = new Condition(LogProductImg.class);
        condition.or().andEqualTo("productId", productId)
                .andEqualTo("baiduDeleted", 0)
                .andIsNotNull("contSign")
                .andNotEqualTo("fromWxUpload", 1)
        ;
        List<LogProductImg> logProductImgList = logProductImgRepository.findByCondition(condition);

        if (logProductImgList != null && logProductImgList.size() > 0) {
            return logProductImgList;
        }
        return null;
    }

    public List<LogProductImgFromUser> getProductImgFromUserList(Integer productId){
        Condition condition = new Condition(LogProductImgFromUser.class);
        condition.setOrderByClause(" id ");
        condition.or().andEqualTo("productId", productId)
                .andEqualTo("baiduDeleted", 0)
                .andIsNotNull("contSign")
        ;
        List<LogProductImgFromUser> logProductImgList = logProductImgFromUserRepository.findByCondition(condition);

        if (logProductImgList != null && logProductImgList.size() > 0) {
            return logProductImgList;
        }
        return null;
    }

    public List<LogProductImgFromUser> getProductImgFromUserListFromCorrect(Integer productId){
        Condition condition = new Condition(LogProductImgFromUser.class);
        condition.setOrderByClause(" id ");
        condition.or().andEqualTo("productId", productId)
                .andEqualTo("fromCorrect", 1)
                .andEqualTo("baiduDeleted", 0)
                .andIsNotNull("contSign")
        ;
        List<LogProductImgFromUser> logProductImgList = logProductImgFromUserRepository.findByCondition(condition);

        if (logProductImgList != null && logProductImgList.size() > 0) {
            return logProductImgList;
        }
        return null;
    }

    public void deleteProductImgFromUserList(List<Integer> idList){
        Condition condition = new Condition(LogProductImgFromUser.class);
        condition.or().andIn("id", idList)
        ;

        LogProductImgFromUser temp = new LogProductImgFromUser();
        temp.setBaiduDeleted(1);

        logProductImgFromUserMapper.updateByConditionSelective(temp, condition);

//        logProductImgFromUserRepository.deleteByCondition(condition);
    }

    public void deleteProductImgList(List<Integer> idList){
        Condition condition = new Condition(LogProductImg.class);
        condition.or().andIn("id", idList)
        ;


        LogProductImg temp = new LogProductImg();
        temp.setBaiduDeleted(1);

        logProductImgMapper.updateByConditionSelective(temp, condition);

//        logProductImgRepository.deleteByCondition(condition);
    }

    public List<MinorCategoryVO> findCategory(Integer shopId){


        List<MinorCategoryVO> minorCategorys = _findCategory(shopId, CategoryType.MAJOR).stream().map(productCategory ->
                MinorCategoryVO.builder()
                .minorCategoryId(productCategory.getId())
                .minorCategoryName(productCategory.getName()).build()
        ).collect(Collectors.toList());
        return minorCategorys;

//        Optional<ProductCategory> categoryO = _findCategory(shopId, CategoryType.MAJOR).stream().findFirst();
//        return categoryO.map(productCategory -> MajorCategoryVO.builder()
//                .majorCategoryId(productCategory.getId())
//                .majorCategoryName(productCategory.getName())
//                .minorCategorys(minorCategorys).build()).orElse(null);
    }

    private List<ProductCategory> _findCategory(Integer shopId, CategoryType categoryType){
        Condition condition = new Condition(ProductCategory.class);
        condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("type", categoryType.getCode().byteValue())
                .andEqualTo("deleted", false);
       return productCategoryRepository.findByCondition(condition);
    }




    public List<ProductVO> findProductsByTime(Integer shopId, Optional<Integer> majorCategoryId, Optional<Integer> minorCategoryId){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 1)
                .andNotEqualTo("productType", 2)
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
        List<ProductVO> productVOS= productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                        .id(product.getId())
                        .shopId(product.getShopid())
                        .majorCategoryId(product.getMajorcategoryid())
                        .minorCategoryId(product.getMinorcategoryid())
                        .name(product.getName())
                        .searchCode(product.getSearchcode())
                        .standard(product.getStandard())
                        .price(product.getPrice())
                        .vipPrice(product.getPrice())
                        .note(product.getNote())
                        .description(product.getDescription())
                        .intro(product.getIntro())
                        .thumbnail(product.getThumbnail())
                        .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());


        String curTime = formatter.format(new Date());
        Condition shopHourConfigCondition = new Condition(ShopHoursConfig.class);
        shopHourConfigCondition.or().andEqualTo("shopId", shopId)
                .andGreaterThan("endTime", curTime)
                .andLessThan("startTime", curTime)
                .andEqualTo("hourType", 2)
        ;
        List<ShopHoursConfig> shopHoursConfigList = shopHoursConfigMapper.selectByCondition(shopHourConfigCondition);

        if (shopHoursConfigList != null && shopHoursConfigList.size() > 0) {
            ShopHoursConfig shopHoursConfig = shopHoursConfigList.get(0);

            List<Integer> productIdList = productVOS.stream().map(ProductVO::getId).collect(Collectors.toList());

            Condition productPriceCondition = new Condition(ProductPrice.class);
            productPriceCondition.or()
                    .andEqualTo("shopHourConfigId", shopHoursConfig.getId())
                    .andIn("productId", productIdList)
                    ;

            List<ProductPrice> productPriceList = productPriceMapper.selectByCondition(productPriceCondition);

            if (productPriceList != null && productPriceList.size() > 0) {
                Map<Integer, Integer> productPriceMap = productPriceList.stream()
                        .collect(Collectors.toMap(ProductPrice::getProductId, ProductPrice::getPrice));
                for(ProductVO p : productVOS){
                    Integer price = productPriceMap.get(p.getId());
                    if (price != null && price >= 0) {
                        p.setPrice(price.longValue());
                    }
                }
            }
        }
        return productVOS;
    }



    public List<ProductVO> findProductsByBranchId(Integer shopId, Optional<Integer> majorCategoryId, Optional<Integer> minorCategoryId
                    ,Integer branchId
    ){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("storeid", branchId)
                .andEqualTo("status", 1)
                .andNotEqualTo("productType", 2)
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
       return productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());
    }

    public List<ProductVO> findProducts(Integer shopId, Optional<Integer> majorCategoryId, Optional<Integer> minorCategoryId){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 1)
                .andNotEqualTo("productType", 2)
//                .andNotEqualTo("searchcode","-5")
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
       return productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());
    }


    public List<ProductVO> findProductsForWX(Integer shopId, Optional<Integer> majorCategoryId, Optional<Integer> minorCategoryId){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 1)
                .andNotEqualTo("productType", 2)
                .andNotEqualTo("searchcode","-5")
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
       return productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());
    }

    public List<ProductVO> findCurProductList(Integer shopId, Integer branchId){
        Condition productSubCondition = new Condition(ProductSub.class);
        productSubCondition.or().andEqualTo("shopId", shopId)
                .andEqualTo("branchId", branchId)
        ;
        List<ProductSub> productSubList = productSubMapper.selectByCondition(productSubCondition);

        if (productSubList != null && productSubList.size() > 0) {
            List<Integer> productIdList =
                    productSubList.stream().map(ProductSub::getProductId).collect(Collectors.toList());
            List<Product> productList = getProductByIdList(productIdList);

            List<ProductVO> list = productList.stream().map(product ->{


                ProductVO productVO = ProductVO.builder()
                        .id(product.getId())
                        .shopId(product.getShopid())
                        .majorCategoryId(product.getMajorcategoryid())
                        .minorCategoryId(product.getMinorcategoryid())
                        .name(product.getName())
                        .searchCode(product.getSearchcode())
                        .standard(product.getStandard())
                        .price(product.getPrice())
                        .vipPrice(product.getPrice())
                        .note(product.getNote())
                        .description(product.getDescription())
                        .intro(product.getIntro())
                        .thumbnail(product.getThumbnail())
                        .productPic(product.getProductpic()).build();

                return productVO;
                }
            ).collect(Collectors.toList());

            Collections.sort(list, Comparator.comparing(ProductVO::getPrice));

            return list;
        }

        return null;
    }

    public List<ProductVO> findBranchProducts(Integer shopId, Optional<Integer> majorCategoryId,
                                              Optional<Integer> minorCategoryId, Integer branchId){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 1)
                .andEqualTo("storeid", branchId)
                .andNotEqualTo("productType", 2)
//                .andNotEqualTo("searchcode","-5")
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
       return productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());
    }

    public List<ProductVO> findBranchProductsForWX(Integer shopId, Optional<Integer> majorCategoryId,
                                              Optional<Integer> minorCategoryId, Integer branchId){
        Condition condition = new Condition(Product.class);
        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 1)
                .andEqualTo("storeid", branchId)
                .andNotEqualTo("productType", 2)
                .andNotEqualTo("searchcode","-5")
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
       return productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());
    }


    public static List<Integer> productStatusList = new ArrayList<>();
    static {
        productStatusList.add(1);
        productStatusList.add(2);

    }

    public List<ProductVO> findMeshProducts(Integer shopId,
                                            Optional<Integer> majorCategoryId,
                                            Optional<Integer> minorCategoryId,
                                            Integer branchId
    ){
        Condition condition = new Condition(Product.class);

        Example.Criteria criteria = condition.or().andEqualTo("shopid", shopId)
                .andIn("status", productStatusList)
                .andEqualTo("productType", 2)
                .andEqualTo("storeid", branchId)
                .andEqualTo("deleted", false);
        majorCategoryId.map(id -> criteria.andEqualTo("majorcategoryid", id));
        minorCategoryId.map(id -> criteria.andEqualTo("minorcategoryid", id));
        List<ProductVO> list = productRepository.findByCondition(condition).stream().map(product ->
                ProductVO.builder()
                .id(product.getId())
                .shopId(product.getShopid())
                .majorCategoryId(product.getMajorcategoryid())
                .minorCategoryId(product.getMinorcategoryid())
                .name(product.getName())
                .searchCode(product.getSearchcode())
                .standard(product.getStandard())
                .price(product.getPrice())
                .vipPrice(product.getPrice())
                .note(product.getNote())
                .description(product.getDescription())
                .intro(product.getIntro())
                .thumbnail(product.getThumbnail())
                .status(product.getStatus().intValue())
                .createTime(product.getCreated())
                .productPic(product.getProductpic()).build()

        ).collect(Collectors.toList());

        if (list != null && list.size() > 0) {
            List<ProductVO> onLineProductList = new ArrayList<>();
            List<ProductVO> offLineProductList = null;
            for (ProductVO productVO : list) {
                if (productVO.getStatus().intValue() == 1) {
                    onLineProductList.add(productVO);
                }else {
                    if (offLineProductList == null) {
                        offLineProductList = new ArrayList<>();
                    }
                    offLineProductList.add(productVO);
                }
            }

            Collections.sort(onLineProductList, Comparator.comparing(ProductVO::getCreateTime).reversed());

            if (offLineProductList != null) {
                Collections.sort(offLineProductList, Comparator.comparing(ProductVO::getCreateTime).reversed());
                onLineProductList.addAll(offLineProductList);
            }


            return onLineProductList;
        }

        return list;
    }


    public String getProductName(Integer productId){
        Product product = productRepository.findById(productId);
        if(product == null) throw new ServiceException(PRODUCT_NOT_EXISTS);
        return product.getName();

    }


    public Product getProductById(Integer productId){
        Product product = productRepository.findById(productId);
        if(product == null) throw new ServiceException(PRODUCT_NOT_EXISTS);
        return product;

    }

    public void addMeshProductImg(Integer shopId, Integer productId, String imgUrl, Integer branchId){
        LogProductImg logProductImg = new LogProductImg();
        logProductImg.setProductId(productId);
        logProductImg.setShopId(shopId);
        logProductImg.setSourceImg(imgUrl);
        logProductImg.setCreateTime(new Date());
        logProductImg.setBaiduDeleted(1);
        logProductImg.setFromWxUpload(1);
        logProductImg.setBranchId(branchId);

        logProductImgMapper.insert(logProductImg);

        Product product = new Product();
        product.setProductpic(imgUrl);
        product.setId(productId);
        productMapper.updateByPrimaryKeySelective(product);
    }

    public ProductInventory getMeshProductById(Integer productId){

        Condition condition = new Condition(ProductInventory.class);
        condition.or().andEqualTo("productId", productId);
        List<ProductInventory> productInventoryList = productInventoryMapper.selectByCondition(condition);

        if (productInventoryList != null && productInventoryList.size() > 0) {
            return productInventoryList.get(0);
        }

        return null;

    }


    public List<Product> getProductByIdList(List<Integer> idList){
        String productIdListStr = org.apache.commons.lang3.StringUtils.join(idList.toArray(), ",");
        List<Product> productList = productRepository.findByIds(productIdListStr);
        if(productList == null) throw new ServiceException(PRODUCT_NOT_EXISTS);
        return productList;

    }

    public List<LogProductImg> getProductImgByProductId(Integer productId){
        Condition condition = new Condition(LogProductImg.class);
        condition.or().andEqualTo("productId", productId);
        return logProductImgRepository.findByCondition(condition);

    }

    public LogProductImg getProductImgById(Integer id){

        return logProductImgRepository.findById(id);

    }


    public LogProductImgFromUser getProductImgFromCorrectById(Integer id){

        return logProductImgFromUserRepository.findById(id);

    }

    public void delProductImgFromUser(Integer productImgId){
        LogProductImgFromUser logProductImg = logProductImgFromUserRepository.findById(productImgId);

        logProductImg.setBaiduDeleted(1);

        logProductImgFromUserRepository.update(logProductImg);
    }
    public String delProductImg(Integer productImgId){
        LogProductImg logProductImg = logProductImgMapper.selectByPrimaryKey(productImgId);

        Product product = productMapper.selectByPrimaryKey(logProductImg.getProductId());

        if (product.getProductpic() != null
                && product.getProductpic().equals(logProductImg.getSourceImg())
                ) {
            List<LogProductImg> logProductImgList = getProductImgByProductId(product.getId());

            String picUrl = null;
            for (LogProductImg temp : logProductImgList) {
                if (temp.getId() != productImgId) {
                    picUrl = temp.getSourceImg();
                    break;
                }
            }
            Product tempProduct = new Product();
            tempProduct.setProductpic(picUrl);
            tempProduct.setId(product.getId());
            productMapper.updateByPrimaryKeySelective(tempProduct);
        }
        logProductImgRepository.deleteById(productImgId);

        return logProductImg.getImgCutNetUrl();
    }

    public void delProductImgList(Integer productId){
        Condition condition = new Condition(LogProductImg.class);
        condition.or().andEqualTo("productId", productId);
        logProductImgRepository.deleteByCondition(condition);
    }

    public void delProductYpRef(Integer productId, Integer shopId){

        Condition condition = new Condition(ProductYpRef.class);
        condition.or().andEqualTo("productId", productId)
                    .andEqualTo("shopId", shopId)
        ;
        productYpRefMapper.deleteByCondition(condition);
    }

    public Product getProductBySearchCode(Integer shopId,
                                          String searchCode){
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("shopid",shopId)
                .andEqualTo("searchcode",searchCode)
                .andEqualTo("deleted",false);
        List<Product> productList = productRepository.findByCondition(condition);
        if(null == productList || productList.size() == 0){
            return null;
        }else {
            return productList.get(0);
        }
    }

    public Product getRuiJingProductBySearchCode(Integer shopId,
                                                 String searchCode){
        Condition condition = new Condition(Product.class);
        condition.or().andEqualTo("shopid",shopId)
                .andEqualTo("searchcode",searchCode);
        List<Product> productList = productRepository.findByCondition(condition);
        if(null == productList || productList.size() == 0){
            return null;
        }else {
            return productList.get(0);
        }
    }

    public ProductCategory saveProductCategory(Integer shopId,
                                               String name){

        Condition condition = new Condition(ProductCategory.class);
        condition.or().andEqualTo("name",name)
                .andEqualTo("deleted",0)
                .andEqualTo("shopid",shopId);

        List<ProductCategory> categoryList = productCategoryRepository.findByCondition(condition);

        if (null != categoryList && categoryList.size() > 0){
            throw new ServiceException("存在重复菜品种类");
        }
        ProductCategory productCategory = new ProductCategory();
        productCategory.setName(name);
        productCategory.setShopid(shopId);
        productCategory.setDeleted(false);
        productCategory.setType(new Byte("1"));
        productCategoryRepository.save(productCategory);
        return productCategory;
    }

    public ProductCategory getProductCategory(Integer shopId,
                                              String name){

        Condition condition = new Condition(ProductCategory.class);
        condition.or().andEqualTo("name",name)
                .andEqualTo("deleted",0)
                .andEqualTo("shopid",shopId);

        List<ProductCategory> categoryList = productCategoryRepository.findByCondition(condition);

        if (null != categoryList && categoryList.size() > 0){
           return categoryList.get(0);
        }else {
            throw new ServiceException("菜品分类名称不存在");
        }
    }

    /*public Product getShopCustomProduct(Integer shopId){
        Product product = new Product();
        List<Product> customProductList = productMapper.getCustomProduct(shopId);
        if (null == customProductList || customProductList.size() == 0){
            product.setShopid(shopId);
            product.setUpdated(new Date());
            product.setCreated(new Date());
            product.setPrice(100L);
            product.setVipprice(100L);
            product.setSearchcode("-5");
            product.setName("自定义菜品");
            product.setStatus(new Byte("1"));
            product.setDeleted(false);
            productRepository.save(product);
        }else {
            product = customProductList.get(0);
        }
        return product;
    }*/


}
